package top.maybesix.tools.toast

import android.content.Context
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.graphics.drawable.NinePatchDrawable
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.annotation.DrawableRes
import top.maybesix.tools.R

/**
 * @author MaybeSix
 * @date 2020/4/8
 * @desc TODO.
 */

object XHToast {
    @ColorInt
    private val DEFAULT_TEXT_COLOR = Color.parseColor("#FFFFFF")

    //蓝色
    @ColorInt
    private val INFO_COLOR = Color.parseColor("#2196F3")

    //黄色
    @ColorInt
    private val WARNING_COLOR = Color.parseColor("#FFA900")

    //绿色
    @ColorInt
    private val SUCCESS_COLOR = Color.parseColor("#52BA97")

    //红色
    @ColorInt
    private val ERROR_COLOR = Color.parseColor("#FD4C5B")


    private const val TOAST_TYPEFACE = "sans-serif-condensed"
    private var currentToast: Toast? = null
    private lateinit var mContext: Context

    /**
     * Toast 替代方法 ：立即显示无需等待
     */
    private var mToast: Toast? = null

    /**
     * 初始化
     * @param context Context
     */
    fun init(context: Context) {
        this.mContext = context
    }

    /**
     * 自定义toast,默认无图标
     */
    @JvmStatic
    @JvmOverloads
    fun normal(
        message: String,
        duration: Int = Toast.LENGTH_SHORT,
        icon: Drawable? = null,
        withIcon: Boolean = false,
        textColor: Int = DEFAULT_TEXT_COLOR,
        @ColorInt tintColor: Int = -1,
        shouldTint: Boolean = false
    ) {
        custom(message, duration, icon, withIcon, textColor, tintColor, shouldTint)?.show()
    }

    @JvmStatic
    @JvmOverloads
    fun normal(
        resId: Int,
        duration: Int = Toast.LENGTH_SHORT,
        icon: Drawable? = null,
        withIcon: Boolean = false,
        textColor: Int = DEFAULT_TEXT_COLOR,
        @ColorInt tintColor: Int = -1,
        shouldTint: Boolean = false
    ) {
        normal(
            mContext.getString(resId),
            duration,
            icon,
            withIcon,
            textColor,
            tintColor,
            shouldTint
        )
    }

    /**
     * 通知
     */
    @JvmStatic
    fun info(
        message: String,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        normal(
            message,
            duration,
            getDrawable(R.drawable.ic_info_outline_white_48dp),
            true,
            DEFAULT_TEXT_COLOR,
            INFO_COLOR,
            true
        )
    }

    @JvmStatic
    fun info(
        resId: Int,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        info(
            mContext.getString(resId),
            duration
        )
    }

    /**
     * 警告
     */
    @JvmStatic
    fun warning(
        message: String,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        normal(
            message,
            duration,
            getDrawable(R.drawable.ic_error_outline_white_48dp),
            true,
            DEFAULT_TEXT_COLOR,
            WARNING_COLOR,
            true
        )
    }

    @JvmStatic
    fun warning(
        resId: Int,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        warning(
            mContext.getString(resId),
            duration
        )
    }


    /**
     * 成功
     */

    @JvmStatic
    fun success(
        message: String,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        normal(
            message,
            duration,
            getDrawable(R.drawable.ic_check_white_48dp),
            true,
            DEFAULT_TEXT_COLOR,
            SUCCESS_COLOR,
            true
        )

    }

    @JvmStatic
    fun success(
        resId: Int,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        success(
            mContext.getString(resId),
            duration
        )

    }

    /**
     * 错误
     */

    @JvmStatic
    fun error(
        message: String,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        normal(
            message,
            duration,
            getDrawable(R.drawable.ic_clear_white_48dp),
            true,
            DEFAULT_TEXT_COLOR,
            ERROR_COLOR,
            true
        )
    }

    @JvmStatic
    fun error(
        resId: Int,
        duration: Int = Toast.LENGTH_SHORT
    ) {
        error(
            mContext.getString(resId),
            duration
        )
    }


    /**
     * 构建显示自定义的toast
     * @param message String 文字
     * @param duration Int 持续时间
     * @param icon Drawable? 图标
     * @param withIcon Boolean 是否带着图标
     * @param textColor Int 文字颜色
     * @param tintColor Int 提示
     * @param shouldTint Boolean 是否有提示
     * @return Toast?
     */
    @JvmStatic
    private fun custom(
        message: String,
        duration: Int,
        icon: Drawable?,
        withIcon: Boolean,
        @ColorInt textColor: Int,
        @ColorInt tintColor: Int = -1,
        shouldTint: Boolean = false
    ): Toast? {
        if (currentToast == null) {
            currentToast = Toast(mContext)
        } else {
            currentToast?.cancel()
            currentToast = null
            currentToast = Toast(mContext)
        }
        val toastLayout =
            (mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater).inflate(
                R.layout.toast_layout,
                null
            )
        val toastIcon = toastLayout.findViewById<ImageView>(R.id.toast_icon)
        val toastTextView = toastLayout.findViewById<TextView>(R.id.toast_text)
        val drawableFrame: Drawable? = if (shouldTint) {
            tint9PatchDrawableFrame(tintColor)
        } else {
            getDrawable(R.drawable.toast_frame)
        }
        setBackground(toastLayout, drawableFrame)
        if (withIcon) {
            requireNotNull(icon) { "Avoid passing 'icon' as null if 'withIcon' is set to true" }
            setBackground(toastIcon, icon)
        } else {
            toastIcon.visibility = View.GONE
        }
        toastTextView.setTextColor(textColor)
        toastTextView.text = message
        toastTextView.typeface = Typeface.create(TOAST_TYPEFACE, Typeface.NORMAL)
        currentToast?.view = toastLayout
        currentToast?.duration = duration
        return currentToast
    }

    @JvmStatic
    private fun tint9PatchDrawableFrame(@ColorInt tintColor: Int): Drawable? {
        val toastDrawable = getDrawable(R.drawable.toast_frame) as NinePatchDrawable?
        toastDrawable?.colorFilter = PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN)
        return toastDrawable
    }


    @JvmStatic
    private fun setBackground(view: View, drawable: Drawable?) {
        view.background = drawable
    }

    @JvmStatic
    private fun getDrawable(@DrawableRes id: Int): Drawable? {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mContext.getDrawable(id)
        } else {
            mContext.resources.getDrawable(id)
        }
    }


    /**
     * 封装了Toast的方法 :需要等待
     *
     * @param context Context
     * @param str     要显示的字符串
     * @param isLong  Toast.LENGTH_LONG / Toast.LENGTH_SHORT
     */
    @JvmStatic
    fun showToast(msg: String?, duration: Int = Toast.LENGTH_SHORT) {
        val toast = Toast.makeText(mContext, "", duration)
        toast.setText(msg)
        toast.show()
    }

    @JvmStatic
    fun showToast(resId: Int, duration: Int = Toast.LENGTH_SHORT) {
        showToast(mContext.getString(resId), duration)
    }

}
